package com.kabao.javafx.snow;

import javafx.animation.AnimationTimer;
import javafx.application.Application;
import javafx.geometry.VPos;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.stage.Stage;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class SnowApp extends Application {
    static final Image FLAKE_IMG = new Image(SnowApp.class.getResource("/img/weather/flake.png").toExternalForm()
            , 5, 5, true, true);

    //雪花数量
    private List<Flake> flakes = new ArrayList<>(2000);
    private int flakeNum = 800;
    private int w = 1024;
    private int h = 800;

    private Random random = new Random();
    Text textFps =new Text("FPS: 0");
    Pane root;

    class Flake extends ImageView {

        private String flakeId;
        private double verSpeed;//下落速度
        private double horSpeed; //水平移动速度

        public Flake() {
            super(FLAKE_IMG);
        }

        public String getFlakeId() {
            return flakeId;
        }

        public void setFlakeId(String flakeId) {
            this.flakeId = flakeId;
        }

        public double getVerSpeed() {
            return verSpeed;
        }

        public void setVerSpeed(double verSpeed) {
            this.verSpeed = verSpeed;
        }

        public double getHorSpeed() {
            return horSpeed;
        }

        public void setHorSpeed(double horSpeed) {
            this.horSpeed = horSpeed;
        }
    }

    @Override
    public void start(Stage primaryStage) throws Exception {
        root = new Pane();
        textFps.setTextOrigin(VPos.TOP);
        textFps.setFill(Color.WHITE);
        textFps.setFont(Font.font(35));

//        root.setPrefSize(w, h);
//        String bgUrl = getClass().getResource("/img/weather/snow_bg.png").toExternalForm();
//        root.setStyle("-fx-background-image: url('"+ bgUrl+"')"); // 灰色背景，便于观察
        root.setStyle("-fx-background-color: #f0f0f0;"); // 灰色背景，便于观察

        Image image = new Image(getClass().getResource("/img/weather/snow_bg.png").toExternalForm());
        ImageView imageView = new ImageView(image);
        //自适应大小
        imageView.fitWidthProperty().bind(root.widthProperty());
        imageView.fitHeightProperty().bind(root.heightProperty());
        //保持宽高比，避免拉伸变形
        imageView.setPreserveRatio(false);
        // 缩放时平滑显示，避免锯齿,可选：如果图片比例与容器不符，设置填充方式（如居中）
        imageView.setSmooth(true);
        root.getChildren().add(imageView);
        root.getChildren().add(textFps);

        initSnow();
        primaryStage.setScene(new Scene(root,w,h));
        primaryStage.setTitle("雪花飘飘");
        primaryStage.show();

        AnimationTimer animationTimer = new AnimationTimer() {
            int times;
            boolean reserve;
            long lastTime = System.nanoTime();
            //一秒= 10亿纳秒
            long ONE_SECOND = 1_000_000_000;
            //差值
            double duration ;
            //fps
            int fps;

            @Override
            public void handle(long now) {
                fps++;
                duration=  duration + (now - lastTime);
                if (duration >= ONE_SECOND) {
                    textFps.setText("FPS: " + fps);
                    fps = 0;
                    duration = 0;
//                    duration = duration - ONE_SECOND;
                }
                lastTime = now;

                //每一帧都会被调用一次,3秒钟移动一次 也即 3*200 = 600,fps为200大概
                times++;
                if (times % 200 == 0) {
                    reserve = true;
                    times = 0;
                }

                for (Flake flake : flakes) {
                    //每次下落旋转效果
                    flake.setRotate((flake.getRotate() + 3) % 360);
                    //下落速度
                    flake.setY(flake.getY() + flake.getVerSpeed());
                    //水平移动
                    flake.setX(flake.getX() + flake.getHorSpeed());
                    //相反方向
                    if (reserve) {
                        double result = flake.getHorSpeed() * -1;
                        flake.setHorSpeed(result);
                    }

                    if (flake.getY() > h) {
                        flake.setX(random.nextDouble() * w);
                        flake.setVerSpeed(random.nextDouble() * 2.5 + 0.5);
                        //缩放效果
                        flake.setScaleX(random.nextDouble() * 0.5 + 0.5);
                        flake.setScaleY(flake.getScaleX());

                        flake.setY(0);
                    }
                    flake.setOpacity(1 - flake.getY() / h);
                }
                reserve = false;
            }
        };
        //启动动画
        animationTimer.start();
    }

    /**
     * 创建雪花
     */
    private void initSnow() {
        for (int i = 0; i < flakeNum; i++) {
            Flake flake = new Flake();
            flake.setFlakeId(i + "");
            flake.setX(random.nextDouble() * w);
            flake.setVerSpeed(random.nextDouble() * 0.5 + 0.5);
            flake.setY(random.nextDouble() * h);
            flake.setScaleX(random.nextDouble() * 0.5 + 0.5);
            flake.setScaleY(flake.getScaleX());
            flake.setRotate(random.nextDouble() * 360);
            flake.setOpacity(1 - flake.getY() / h);
            //水平方向移动位置
            flake.setHorSpeed(random.nextDouble() - 0.5);

            flakes.add(flake);
        }
        root.getChildren().addAll(flakes);
    }

    public static void main(String[] args) {
        launch(args);
    }
}
